package com.reactim.user.service.impl;

import com.reactim.user.entity.FriendRequest;
import com.reactim.user.service.FriendNotificationService;
import com.reactim.user.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 好友通知服务实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class FriendNotificationServiceImpl implements FriendNotificationService {

    private final UserService userService;
    private final SimpMessagingTemplate messagingTemplate;

    private static final String WEBSOCKET_TOPIC_PREFIX = "/topic/user/";
    private static final String KAFKA_TOPIC_FRIEND_NOTIFICATION = "friend-notification";

    @Override
    public void sendFriendRequestNotification(FriendRequest request) {
        try {
            // 构建通知消息
            Map<String, Object> notification = buildNotificationMessage(
                    "FRIEND_REQUEST_RECEIVED",
                    "收到新的好友请求",
                    request.getFromUserId(),
                    request.getToUserId(),
                    Map.of(
                            "requestId", request.getId(),
                            "message", request.getMessage() != null ? request.getMessage() : "",
                            "fromUserId", request.getFromUserId(),
                            "expiredAt", request.getExpiredAt()));

            // WebSocket实时推送
            sendWebSocketNotification(request.getToUserId(), notification);

            // Kafka异步处理
            sendKafkaNotification(notification);

            log.info("发送好友请求通知: fromUserId={}, toUserId={}, requestId={}",
                    request.getFromUserId(), request.getToUserId(), request.getId());

        } catch (Exception e) {
            log.error("发送好友请求通知失败: requestId={}", request.getId(), e);
        }
    }

    @Override
    public void sendFriendRequestAcceptedNotification(FriendRequest request) {
        try {
            // 构建通知消息
            Map<String, Object> notification = buildNotificationMessage(
                    "FRIEND_REQUEST_ACCEPTED",
                    "好友请求已被接受",
                    request.getToUserId(),
                    request.getFromUserId(),
                    Map.of(
                            "requestId", request.getId(),
                            "acceptedUserId", request.getToUserId(),
                            "processedAt", request.getProcessedAt()));

            // WebSocket实时推送
            sendWebSocketNotification(request.getFromUserId(), notification);

            // Kafka异步处理
            sendKafkaNotification(notification);

            log.info("发送好友请求接受通知: fromUserId={}, toUserId={}, requestId={}",
                    request.getFromUserId(), request.getToUserId(), request.getId());

        } catch (Exception e) {
            log.error("发送好友请求接受通知失败: requestId={}", request.getId(), e);
        }
    }

    @Override
    public void sendFriendRequestRejectedNotification(FriendRequest request) {
        try {
            // 构建通知消息
            Map<String, Object> notification = buildNotificationMessage(
                    "FRIEND_REQUEST_REJECTED",
                    "好友请求已被拒绝",
                    request.getToUserId(),
                    request.getFromUserId(),
                    Map.of(
                            "requestId", request.getId(),
                            "rejectedUserId", request.getToUserId(),
                            "rejectReason", request.getRejectReason() != null ? request.getRejectReason() : "",
                            "processedAt", request.getProcessedAt()));

            // WebSocket实时推送
            sendWebSocketNotification(request.getFromUserId(), notification);

            // Kafka异步处理
            sendKafkaNotification(notification);

            log.info("发送好友请求拒绝通知: fromUserId={}, toUserId={}, requestId={}",
                    request.getFromUserId(), request.getToUserId(), request.getId());

        } catch (Exception e) {
            log.error("发送好友请求拒绝通知失败: requestId={}", request.getId(), e);
        }
    }

    @Override
    public void sendFriendRequestCancelledNotification(FriendRequest request) {
        try {
            // 构建通知消息
            Map<String, Object> notification = buildNotificationMessage(
                    "FRIEND_REQUEST_CANCELLED",
                    "好友请求已被取消",
                    request.getFromUserId(),
                    request.getToUserId(),
                    Map.of(
                            "requestId", request.getId(),
                            "cancelledUserId", request.getFromUserId(),
                            "processedAt", request.getProcessedAt()));

            // WebSocket实时推送
            sendWebSocketNotification(request.getToUserId(), notification);

            // Kafka异步处理
            sendKafkaNotification(notification);

            log.info("发送好友请求取消通知: fromUserId={}, toUserId={}, requestId={}",
                    request.getFromUserId(), request.getToUserId(), request.getId());

        } catch (Exception e) {
            log.error("发送好友请求取消通知失败: requestId={}", request.getId(), e);
        }
    }

    @Override
    public void sendNewFriendAddedNotification(Long userId, Long friendId) {
        try {
            // 构建通知消息
            Map<String, Object> notification = buildNotificationMessage(
                    "NEW_FRIEND_ADDED",
                    "添加了新好友",
                    friendId,
                    userId,
                    Map.of(
                            "newFriendId", friendId,
                            "addedAt", LocalDateTime.now()));

            // WebSocket实时推送
            sendWebSocketNotification(userId, notification);

            // Kafka异步处理
            sendKafkaNotification(notification);

            log.info("发送新好友添加通知: userId={}, friendId={}", userId, friendId);

        } catch (Exception e) {
            log.error("发送新好友添加通知失败: userId={}, friendId={}", userId, friendId, e);
        }
    }

    @Override
    public void sendFriendRemovedNotification(Long userId, Long friendId) {
        try {
            // 构建通知消息
            Map<String, Object> notification = buildNotificationMessage(
                    "FRIEND_REMOVED",
                    "好友已被删除",
                    friendId,
                    userId,
                    Map.of(
                            "removedFriendId", friendId,
                            "removedAt", LocalDateTime.now()));

            // WebSocket实时推送
            sendWebSocketNotification(userId, notification);

            // Kafka异步处理
            sendKafkaNotification(notification);

            log.info("发送好友删除通知: userId={}, friendId={}", userId, friendId);

        } catch (Exception e) {
            log.error("发送好友删除通知失败: userId={}, friendId={}", userId, friendId, e);
        }
    }

    /**
     * 构建通知消息
     */
    private Map<String, Object> buildNotificationMessage(String type, String message,
            Long fromUserId, Long toUserId,
            Map<String, Object> data) {
        Map<String, Object> notification = new HashMap<>();
        notification.put("type", type);
        notification.put("message", message);
        notification.put("fromUserId", fromUserId);
        notification.put("toUserId", toUserId);
        notification.put("timestamp", LocalDateTime.now());
        notification.put("data", data);

        return notification;
    }

    /**
     * 发送WebSocket通知
     */
    private void sendWebSocketNotification(Long userId, Map<String, Object> notification) {
        try {
            String destination = WEBSOCKET_TOPIC_PREFIX + userId + "/friend-notifications";
            messagingTemplate.convertAndSend(destination, notification);
            
            log.info("WebSocket通知发送成功: userId={}, type={}, destination={}", 
                    userId, notification.get("type"), destination);
        } catch (Exception e) {
            log.error("WebSocket通知发送失败: userId={}, type={}", 
                    userId, notification.get("type"), e);
        }
    }

    /**
     * 发送Kafka通知（简化版本，仅记录日志）
     */
    private void sendKafkaNotification(Map<String, Object> notification) {
        // 暂时只记录日志，后续可以集成Kafka
        log.info("Kafka通知（模拟）: type={}, message={}", 
                notification.get("type"), notification.get("message"));
    }
}